import json
import time
from datetime import datetime
from pynput import keyboard, mouse
from pynput.keyboard import Key, KeyCode
from collections import deque
import threading

class InputRecorder:
    def __init__(self):
        self.recording = False
        self.start_time = 0
        self.events = []
        self.session_id = datetime.now().strftime("%Y-%m-%d-%H%M%S")
        self.video_name = f"recording_{self.session_id}"

        # 初始化监听器
        self.keyboard_listener = keyboard.Listener(on_press=self.on_key_press, on_release=self.on_key_release)
        self.mouse_listener = mouse.Listener(on_click=self.on_click, on_scroll=self.on_scroll)

    def on_key_press(self, key):
        """处理按键按下事件"""
        try:
            # 检查是否是SCRLK键（Scroll Lock）
            if hasattr(key, 'name') and key.name == 'scroll_lock':
                self.toggle_recording()
                return

            if self.recording:
                current_time = time.time() - self.start_time
                key_name = key.char if hasattr(key, 'char') and key.char else str(key).replace('Key.', '')

                event = {
                    "type": "key_press",
                    "key": key_name,
                    "timestamp": round(current_time, 3)
                }
                self.events.append(event)
                print(f"记录按键按下: {key_name} at {current_time:.3f}s")

        except Exception as e:
            print(f"处理按键按下时出错: {e}")

    def on_key_release(self, key):
        """处理按键释放事件"""
        if self.recording:
            try:
                # 忽略SCRLK键的释放事件
                if hasattr(key, 'name') and key.name == 'scroll_lock':
                    return

                current_time = time.time() - self.start_time
                key_name = key.char if hasattr(key, 'char') and key.char else str(key).replace('Key.', '')

                event = {
                    "type": "key_release",
                    "key": key_name,
                    "timestamp": round(current_time, 3)
                }
                self.events.append(event)
            except Exception as e:
                print(f"处理按键释放时出错: {e}")

    def on_click(self, x, y, button, pressed):
        """处理鼠标点击事件"""
        if self.recording:
            current_time = time.time() - self.start_time
            action = "按下" if pressed else "释放"
            event = {
                "type": f"mouse_{'press' if pressed else 'release'}",
                "button": str(button).replace('Button.', ''),
                "x": x,
                "y": y,
                "timestamp": round(current_time, 3)
            }
            self.events.append(event)
            print(f"记录鼠标{action}: {button} at {current_time:.3f}s")

    def on_scroll(self, x, y, dx, dy):
        """处理鼠标滚动事件"""
        if self.recording:
            current_time = time.time() - self.start_time
            event = {
                "type": "mouse_scroll",
                "dx": dx,
                "dy": dy,
                "x": x,
                "y": y,
                "timestamp": round(current_time, 3)
            }
            self.events.append(event)
            print(f"记录鼠标滚动: dx={dx}, dy={dy} at {current_time:.3f}s")

    def toggle_recording(self):
        """切换录制状态"""
        if not self.recording:
            # 开始录制
            self.recording = True
            self.start_time = time.time()
            self.events = []
            print("开始记录输入...")
            print("按下SCRLK键停止记录")
        else:
            # 停止录制
            self.recording = False
            duration = time.time() - self.start_time
            print(f"停止记录输入，时长: {duration:.2f}秒")
            self.export_to_json(duration)

    def export_to_json(self, duration):
        """将记录的数据导出为JSON格式"""
        # 处理运动数据
        movement_events = self.process_movement_events()
        view_events = self.process_view_events()

        # 构建JSON数据结构
        data = {
            "game_metadata": {
                "session_id": self.session_id,
                "video_name": self.video_name,
                "start_time": datetime.fromtimestamp(self.start_time).isoformat(),
                "duration_seconds": round(duration, 3)
            },
            "movement_events": movement_events,
            "view_events": view_events,
            # 以下为可选项，可根据需要实现具体数据收集
            "kinematic_data": [],
            "additional_states": []
        }

        # 生成文件名
        filename = f"input_recording_{self.session_id}.json"

        # 写入JSON文件
        with open(filename, 'w') as f:
            json.dump(data, f, indent=2)

        print(f"记录已导出到: {filename}")

    def process_movement_events(self):
        """处理移动事件（示例实现，需要根据实际游戏调整）"""
        # 这里是示例实现，实际应用中需要根据按键事件分析移动方向
        movement_events = []
        key_states = {}

        for event in self.events:
            if event['type'] in ['key_press', 'key_release']:
                key = event['key']
                is_press = event['type'] == 'key_press'

                if key in ['w', 'a', 's', 'd', 'up', 'down', 'left', 'right']:
                    if is_press:
                        key_states[key] = event['timestamp']
                    else:
                        if key in key_states:
                            movement_events.append({
                                "direction": key.upper(),
                                "start_time": round(key_states[key], 3),
                                "end_time": round(event['timestamp'], 3)
                            })
                            del key_states[key]

        return movement_events

    def process_view_events(self):
        """处理视角事件（示例实现，需要根据实际游戏调整）"""
        # 这里是示例实现，实际应用中需要根据鼠标事件分析视角变化
        view_events = []
        # 简单示例：将鼠标移动视为视角变化
        last_mouse_time = self.start_time
        neutral_start = 0.0

        for event in self.events:
            if event['type'] in ['mouse_scroll', 'mouse_press']:
                current_time = event['timestamp']
                if current_time - last_mouse_time > 0.5:  # 0.5秒内无操作视为中性
                    if neutral_start != last_mouse_time:
                        view_events.append({
                            "direction": "Neutral",
                            "start_time": round(neutral_start, 3),
                            "end_time": round(last_mouse_time, 3)
                        })
                    neutral_start = current_time

                # 根据事件类型确定方向
                direction = "U" if event['type'] == 'mouse_scroll' and event['dy'] > 0 else "D"
                view_events.append({
                    "direction": direction,
                    "start_time": round(current_time, 3),
                    "end_time": round(current_time + 0.1, 3)  # 短暂事件
                })

                last_mouse_time = current_time

        return view_events

    def start(self):
        """启动监听器"""
        print("输入记录器已启动...")
        print("按下SCRLK键开始记录")
        self.keyboard_listener.start()
        self.mouse_listener.start()
        self.keyboard_listener.join()
        self.mouse_listener.join()

if __name__ == "__main__":
    recorder = InputRecorder()
    recorder.start()